package com.kmxd.ams.app.system.command;

import static com.kmxd.ams.core.common.constant.Constants.DEFAULT_CROP_ID;
import static com.kmxd.ams.core.common.constant.RoleConst.*;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.kmxd.ams.client.system.*;
import com.kmxd.ams.client.system.dto.SysCropAddDTO;
import com.kmxd.ams.client.system.dto.SysFondsAddDTO;
import com.kmxd.ams.client.system.dto.SysRoleAssignMenuDTO;
import com.kmxd.ams.client.system.dto.SysUserAddDTO;
import com.kmxd.ams.core.common.constant.RoleConst;
import com.kmxd.ams.core.common.enums.DataScopeTypeEnum;
import com.kmxd.ams.core.common.enums.MenuGroupEnum;
import com.kmxd.ams.infra.system.entity.SysCrop;
import com.kmxd.ams.infra.system.entity.SysDept;
import com.kmxd.ams.infra.system.entity.SysMenu;
import com.kmxd.ams.infra.system.entity.SysRole;
import java.util.List;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;

/**
 * 新建单位初始化内容
 *
 * @author ZuoLG
 */
@Slf4j
@AllArgsConstructor
@Service
public class InitCropCmd {
  private ISysDeptSvc sysDeptSvc;
  private ISysFondsSvc sysFondsSvc;
  private ISysUserSvc sysUserSvc;
  private ISysRoleSvc sysRoleSvc;
  private ISysMenuSvc sysMenuSvc;

  /**
   * 新建单位初始化对象 // 1、新建部门档案室 2、新建默认全宗 3、新建角色（档案管理员，普通用户，兼职人员，三元角色） 4、新建全宗管理员用户
   *
   * @param entity
   * @param req
   * @return
   */
  public boolean initCrop(SysCrop entity, SysCropAddDTO req) {
    List<Long> postIds = Lists.newArrayList();
    // 1、新建部门档案室
    SysDept dept = new SysDept();
    dept.setId(ObjectUtil.isNotEmpty(req.getDefDeptId()) ? req.getDefDeptId() : IdWorker.getId());
    dept.setComId(entity.getId());
    dept.setCode(StrUtil.format(RoleConst.DEF_DEFT_CODE, entity.getCode()));
    dept.setName(RoleConst.DEF_DEFT_NAME);
    dept.setStatus(0);
    dept.setDeptType(0);
    sysDeptSvc.save(dept);
    // 3、新建角色（档案管理员，普通用户，兼职人员，三元角色）
    SysRole roleArchAdminBO = roleArchAdmin(entity);
    SysRole roleDefUserBO = roleDefUser(entity);
    SysRole roleCollectUserBO = roleCollectUser(entity);
    SysRole roleParttimeUserBO = roleParttimeUser(entity);
    SysRole roleSysAdminBO = roleSysAdmin(entity);
    SysRole roleSecuritBO = roleSecurit(entity);
    SysRole roleAuditBO = roleAudit(entity);
    // 增加角色 全宗角色：单位领导 全宗角色：档案部门领导 ，部门角色：部门领导
    SysRole roleUnitLeaderBO = roleUnitLeader(entity);
    SysRole roleArchDeptLeaderBO = roleArchDeptLeader(entity);
    SysRole roleDeptLeaderBO = roleDeptLeader(entity);

    List<SysRole> roles = Lists.newArrayList();
    roles.add(roleArchAdminBO);
    roles.add(roleDefUserBO);
    roles.add(roleCollectUserBO);
    roles.add(roleParttimeUserBO);
    roles.add(roleSysAdminBO);
    roles.add(roleSecuritBO);
    roles.add(roleAuditBO);
    roles.add(roleUnitLeaderBO);
    roles.add(roleArchDeptLeaderBO);
    roles.add(roleDeptLeaderBO);
    sysRoleSvc.saveBatch(roles);

    postIds.clear();
    postIds.add(1621044363309000002L);
    // 4、新建全宗管理员用户
    SysUserAddDTO user = new SysUserAddDTO();
    user.setAccount(req.getAdminUser());
    user.setPassword(req.getAdminPwd());
    if (StrUtil.isNotBlank(entity.getShortName())) {
      user.setRealname(StrUtil.format("{}-" + ROLE_SYS_ADMIN, entity.getShortName()));
      user.setNickname(StrUtil.format("{}-" + ROLE_SYS_ADMIN, entity.getShortName()));
    } else {
      user.setRealname(ROLE_SYS_ADMIN);
      user.setNickname(ROLE_SYS_ADMIN);
    }
    user.setDeptId(dept.getId());
    user.setLockFlag("0");
    user.setSex("1");
    user.setStatus("0");
    user.setRoleIds(roleSysAdminBO.getId());
    user.setPostIds(postIds);
    sysUserSvc.add(user);
    // 如果开启三元，则新建【安全管理员】用户
    if (NumberUtil.equals(entity.getDivide(), 1)) {
      postIds.clear();
      postIds.add(1621044363309000000L);
      SysUserAddDTO userSecurity = new SysUserAddDTO();
      userSecurity.setAccount(req.getSecurityUser());
      userSecurity.setPassword(req.getSecurityPwd());
      if (StrUtil.isNotBlank(entity.getShortName())) {
        userSecurity.setRealname(StrUtil.format("{}-" + ROLE_SECURIT, entity.getShortName()));
        userSecurity.setNickname(StrUtil.format("{}-" + ROLE_SECURIT, entity.getShortName()));
      } else {
        userSecurity.setRealname(ROLE_SYS_ADMIN);
        userSecurity.setNickname(ROLE_SYS_ADMIN);
      }
      userSecurity.setDeptId(dept.getId());
      userSecurity.setLockFlag("0");
      userSecurity.setSex("1");
      userSecurity.setStatus("0");
      userSecurity.setRoleIds(roleSecuritBO.getId());
      userSecurity.setPostIds(postIds);
      sysUserSvc.add(user);
    }
    // 初始化菜单资源
    initMenu(entity, roles);
    // 2、新建默认全宗
    SysFondsAddDTO fonds = new SysFondsAddDTO();
    fonds.setId(IdWorker.getId());
    fonds.setComId(entity.getId());
    fonds.setCode(req.getFondsCode());
    fonds.setName(req.getFondsName());
    fonds.setCopyFlag(req.getCopyFlag());
    fonds.setCopyFondsId(req.getCopyFondsId());
    fonds.setArchType(req.getArchType());
    fonds.setOtherConfig(req.getOtherConfig());
    sysFondsSvc.add(fonds);

    // 初始化测试人员-开发模式会添加此人员信息
    if (ObjectUtil.equals(entity.getId(), DEFAULT_CROP_ID)) {
      initUser(
          req,
          postIds,
          dept,
          roleArchAdminBO,
          roleDefUserBO,
          roleCollectUserBO,
          roleParttimeUserBO,
          roleSecuritBO,
          roleAuditBO);
    }

    sysDeptSvc.clearAllCache();
    sysFondsSvc.clearAllCache();
    
    return true;
  }

  private void initUser(
      SysCropAddDTO req,
      List<Long> postIds,
      SysDept dept,
      SysRole roleArchAdminBO,
      SysRole roleDefUserBO,
      SysRole roleCollectUserBO,
      SysRole roleParttimeUserBO,
      SysRole roleSecuritBO,
      SysRole roleAuditBO) {
    // 普通员工
    postIds.clear();
    postIds.add(1621044363309000000L);
    // 初始化采集员
    SysUserAddDTO cjy = new SysUserAddDTO();
    cjy.setAccount("cjy");
    cjy.setDeptId(dept.getId());
    cjy.setLockFlag("0");
    cjy.setPassword(req.getAdminPwd());
    cjy.setRealname(ROLE_SINGLE_USER);
    cjy.setRoleIds(roleCollectUserBO.getId());
    cjy.setSex("1");
    cjy.setStatus("0");
    cjy.setSort(1);
    cjy.setPostIds(postIds);

    // 档案管理员
    SysUserAddDTO dagly = new SysUserAddDTO();
    dagly.setAccount("dagly");
    dagly.setDeptId(dept.getId());
    dagly.setLockFlag("0");
    dagly.setPassword(req.getAdminPwd());
    dagly.setRealname(ROLE_ARCH_ADMIN);
    dagly.setRoleIds(roleArchAdminBO.getId());
    dagly.setSex("1");
    dagly.setStatus("0");
    dagly.setSort(1);
    dagly.setPostIds(postIds);

    // 初始化兼职人员
    SysUserAddDTO jzy = new SysUserAddDTO();
    jzy.setAccount("jzy");
    jzy.setDeptId(dept.getId());
    jzy.setLockFlag("0");
    jzy.setPassword(req.getAdminPwd());
    jzy.setRealname(ROLE_PARTTIME_USER);
    jzy.setRoleIds(roleParttimeUserBO.getId());
    jzy.setSex("1");
    jzy.setStatus("0");
    jzy.setSort(1);
    jzy.setPostIds(postIds);

    // 初始化安全管理员
    SysUserAddDTO aqgly = new SysUserAddDTO();
    aqgly.setAccount("aqgly");
    aqgly.setDeptId(dept.getId());
    aqgly.setLockFlag("0");
    aqgly.setPassword(req.getAdminPwd());
    aqgly.setRealname(ROLE_SECURIT);
    aqgly.setRoleIds(roleSecuritBO.getId());
    aqgly.setSex("1");
    aqgly.setStatus("0");
    aqgly.setSort(1);
    aqgly.setPostIds(postIds);

    // 初始化安全审计员
    SysUserAddDTO aqsjy = new SysUserAddDTO();
    aqsjy.setAccount("aqsjy");
    aqsjy.setDeptId(dept.getId());
    aqsjy.setLockFlag("0");
    aqsjy.setPassword(req.getAdminPwd());
    aqsjy.setRealname(ROLE_AUDIT);
    aqsjy.setRoleIds(roleAuditBO.getId());
    aqsjy.setSex("1");
    aqsjy.setStatus("0");
    aqsjy.setSort(1);
    aqsjy.setPostIds(postIds);

    sysUserSvc.add(cjy);
    sysUserSvc.add(dagly);
    sysUserSvc.add(jzy);
    sysUserSvc.add(aqgly);
    sysUserSvc.add(aqsjy);
  }

  /**
   * 此代码用于临时测试
   *
   * @param req
   * @param postIds
   * @param dept
   * @param roleArchAdminBO
   * @param roleDefUserBO
   * @param roleCollectUserBO
   * @param roleParttimeUserBO
   * @param roleSecuritBO
   * @param roleAuditBO
   */
  private void initUser2(
      SysCropAddDTO req,
      List<Long> postIds,
      SysDept dept,
      SysRole roleArchAdminBO,
      SysRole roleDefUserBO,
      SysRole roleCollectUserBO,
      SysRole roleParttimeUserBO,
      SysRole roleSecuritBO,
      SysRole roleAuditBO) {
    // 普通员工
    postIds.clear();
    postIds.add(1621044363309000000L);
    // 初始化采集员
    SysUserAddDTO cjy = new SysUserAddDTO();
    cjy.setAccount("cjy2");
    cjy.setDeptId(dept.getId());
    cjy.setLockFlag("0");
    cjy.setPassword(req.getAdminPwd());
    cjy.setRealname(ROLE_SINGLE_USER);
    cjy.setRoleIds(roleCollectUserBO.getId());
    cjy.setSex("1");
    cjy.setStatus("0");
    cjy.setSort(1);
    cjy.setPostIds(postIds);

    // 档案管理员
    SysUserAddDTO dagly = new SysUserAddDTO();
    dagly.setAccount("dagly2");
    dagly.setDeptId(dept.getId());
    dagly.setLockFlag("0");
    dagly.setPassword(req.getAdminPwd());
    dagly.setRealname(ROLE_ARCH_ADMIN);
    dagly.setRoleIds(roleArchAdminBO.getId());
    dagly.setSex("1");
    dagly.setStatus("0");
    dagly.setSort(1);
    dagly.setPostIds(postIds);

    // 初始化兼职人员
    SysUserAddDTO jzy = new SysUserAddDTO();
    jzy.setAccount("jzy2");
    jzy.setDeptId(dept.getId());
    jzy.setLockFlag("0");
    jzy.setPassword(req.getAdminPwd());
    jzy.setRealname(ROLE_PARTTIME_USER);
    jzy.setRoleIds(roleParttimeUserBO.getId());
    jzy.setSex("1");
    jzy.setStatus("0");
    jzy.setSort(1);
    jzy.setPostIds(postIds);

    // 初始化安全管理员
    SysUserAddDTO aqgly = new SysUserAddDTO();
    aqgly.setAccount("aqgly2");
    aqgly.setDeptId(dept.getId());
    aqgly.setLockFlag("0");
    aqgly.setPassword(req.getAdminPwd());
    aqgly.setRealname(ROLE_SECURIT);
    aqgly.setRoleIds(roleSecuritBO.getId());
    aqgly.setSex("1");
    aqgly.setStatus("0");
    aqgly.setSort(1);
    aqgly.setPostIds(postIds);

    // 初始化安全审计员
    SysUserAddDTO aqsjy = new SysUserAddDTO();
    aqsjy.setAccount("aqsjy2");
    aqsjy.setDeptId(dept.getId());
    aqsjy.setLockFlag("0");
    aqsjy.setPassword(req.getAdminPwd());
    aqsjy.setRealname(ROLE_AUDIT);
    aqsjy.setRoleIds(roleAuditBO.getId());
    aqsjy.setSex("1");
    aqsjy.setStatus("0");
    aqsjy.setSort(1);
    aqsjy.setPostIds(postIds);

    sysUserSvc.add(cjy);
    sysUserSvc.add(dagly);
    sysUserSvc.add(jzy);
    sysUserSvc.add(aqgly);
    sysUserSvc.add(aqsjy);
  }

  /**
   * 档案管理员
   *
   * @param entity
   * @return
   */
  public SysRole roleArchAdmin(SysCrop entity) {
    SysRole sysRole = new SysRole();
    sysRole.setId(IdWorker.getId());
    sysRole.setRoleCode(StrUtil.format(ROLE_ARCH_ADMIN_CODE, entity.getId()));
    sysRole.setComId(entity.getId());
    sysRole.setRoleName(ROLE_ARCH_ADMIN);
    sysRole.setRoleType(DataScopeTypeEnum.FONDS.getType());
    sysRole.setRoleSensitive(1);
    sysRole.setDataScope("0");
    return sysRole;
  }

  /**
   * 默认普通用户 获取所有角色的功能菜单
   *
   * @param entity
   * @return
   */
  public SysRole roleDefUser(SysCrop entity) {
    SysRole sysRole = new SysRole();
    sysRole.setId(IdWorker.getId());
    sysRole.setRoleCode(StrUtil.format(ROLE_DEF_USER_CODE, entity.getId()));
    sysRole.setComId(entity.getId());
    sysRole.setRoleName(ROLE_DEF_USER);
    sysRole.setRoleType(DataScopeTypeEnum.USER.getType());
    sysRole.setRoleSensitive(2);
    sysRole.setDataScope("0");
    return sysRole;
  }

  /**
   * 采集员 个人角色功能菜单
   *
   * @param entity
   * @return
   */
  public SysRole roleCollectUser(SysCrop entity) {
    SysRole sysRole = new SysRole();
    sysRole.setId(IdWorker.getId());
    sysRole.setRoleCode(StrUtil.format(ROLE_SINGLE_USER_CODE, entity.getId()));
    sysRole.setComId(entity.getId());
    sysRole.setRoleName(ROLE_SINGLE_USER);
    sysRole.setRoleType(DataScopeTypeEnum.USER.getType());
    sysRole.setRoleSensitive(1);
    sysRole.setDataScope("1");
    return sysRole;
  }

  /**
   * 兼职人员
   *
   * @param entity
   * @return
   */
  public SysRole roleParttimeUser(SysCrop entity) {
    SysRole sysRole = new SysRole();
    sysRole.setId(IdWorker.getId());
    sysRole.setRoleCode(StrUtil.format(ROLE_PARTTIME_USER_CODE, entity.getId()));
    sysRole.setComId(entity.getId());
    sysRole.setRoleName(ROLE_PARTTIME_USER);
    sysRole.setRoleType(DataScopeTypeEnum.DEPT.getType());
    sysRole.setRoleSensitive(1);
    sysRole.setDataScope("1");
    return sysRole;
  }

  /**
   * 三元-系统管理员
   *
   * @param entity
   * @return
   */
  public SysRole roleSysAdmin(SysCrop entity) {
    SysRole sysRole = new SysRole();
    sysRole.setId(IdWorker.getId());
    sysRole.setRoleCode(StrUtil.format(ROLE_SYS_ADMIN_CODE, entity.getId()));
    sysRole.setComId(entity.getId());
    sysRole.setRoleName(ROLE_SYS_ADMIN);
    sysRole.setRoleType(DataScopeTypeEnum.FONDS.getType());
    sysRole.setRoleSensitive(1);
    sysRole.setDataScope("0");
    return sysRole;
  }

  /**
   * 三元-安全保密员(安全管理员)
   *
   * @param entity
   * @return
   */
  public SysRole roleSecurit(SysCrop entity) {
    SysRole sysRole = new SysRole();
    sysRole.setId(IdWorker.getId());
    sysRole.setRoleCode(StrUtil.format(ROLE_SECURIT_CODE, entity.getId()));
    sysRole.setComId(entity.getId());
    sysRole.setRoleName(ROLE_SECURIT);
    sysRole.setRoleType(DataScopeTypeEnum.DEPT.getType());
    sysRole.setRoleSensitive(1);
    sysRole.setDataScope("0");
    return sysRole;
  }

  /**
   * 三元-安全审计员
   *
   * @param entity
   * @return
   */
  public SysRole roleAudit(SysCrop entity) {
    SysRole sysRole = new SysRole();
    sysRole.setId(IdWorker.getId());
    sysRole.setRoleCode(StrUtil.format(ROLE_AUDIT_CODE, entity.getId()));
    sysRole.setComId(entity.getId());
    sysRole.setRoleName(ROLE_AUDIT);
    sysRole.setRoleType(DataScopeTypeEnum.DEPT.getType());
    sysRole.setRoleSensitive(1);
    sysRole.setDataScope("0");
    return sysRole;
  }

  /**
   * 单位领导
   *
   * @param entity
   * @return
   */
  public SysRole roleUnitLeader(SysCrop entity) {
    SysRole sysRole = new SysRole();
    sysRole.setId(IdWorker.getId());
    sysRole.setRoleCode(StrUtil.format(ROLE__UNIT_LEADER_CODE, entity.getId()));
    sysRole.setComId(entity.getId());
    sysRole.setRoleName(ROLE_UNIT_LEADER);
    sysRole.setRoleType(DataScopeTypeEnum.FONDS.getType());
    sysRole.setRoleSensitive(1);
    sysRole.setDataScope("0");
    return sysRole;
  }

  /**
   * 档案部门领导
   *
   * @param entity
   * @return
   */
  public SysRole roleArchDeptLeader(SysCrop entity) {
    SysRole sysRole = new SysRole();
    sysRole.setId(IdWorker.getId());
    sysRole.setRoleCode(StrUtil.format(ROLE_ARCH_DEPT_LEADER_CODE, entity.getId()));
    sysRole.setComId(entity.getId());
    sysRole.setRoleName(ROLE_ARCH_DEPT_LEADER);
    sysRole.setRoleType(DataScopeTypeEnum.DEPT.getType());
    sysRole.setRoleSensitive(1);
    sysRole.setDataScope("0");
    return sysRole;
  }

  /**
   * 部门领导
   *
   * @param entity
   * @return
   */
  public SysRole roleDeptLeader(SysCrop entity) {
    SysRole sysRole = new SysRole();
    sysRole.setId(IdWorker.getId());
    sysRole.setRoleCode(StrUtil.format(ROLE_DEPT_LEADER_CODE, entity.getId()));
    sysRole.setComId(entity.getId());
    sysRole.setRoleName(ROLE_DEPT_LEADER);
    sysRole.setRoleType(DataScopeTypeEnum.DEPT.getType());
    sysRole.setRoleSensitive(1);
    sysRole.setDataScope("0");
    return sysRole;
  }

  /**
   * 初始化菜单
   *
   * @param entity
   * @param roles
   */
  public void initMenu(SysCrop entity, List<SysRole> roles) {
    List<SysMenu> menuList = sysMenuSvc.list();
    List<Long> menuListIds = menuList.stream().map(SysMenu::getId).collect(Collectors.toList());
    List<SysRoleAssignMenuDTO> assignMenuList = Lists.newArrayList();
    roles.forEach(
        role -> {
          SysRoleAssignMenuDTO assignMenuDTO = new SysRoleAssignMenuDTO();
          // 档案管理员
          if (StrUtil.equalsIgnoreCase(
              role.getRoleCode(), StrUtil.format(ROLE_ARCH_ADMIN_CODE, entity.getId()))) {
            assignMenuDTO.setMenuIds(sysMenuSvc.selectMenuByRole(MenuGroupEnum.FONDS, menuList));
          }
          // 普通用户
          if (StrUtil.equalsIgnoreCase(
              role.getRoleCode(), StrUtil.format(ROLE_DEF_USER_CODE, entity.getId()))) {
            assignMenuDTO.setMenuIds(sysMenuSvc.selectMenuByRole(MenuGroupEnum.ALL, menuList));
          }
          // 采集员
          if (StrUtil.equalsIgnoreCase(
              role.getRoleCode(), StrUtil.format(ROLE_SINGLE_USER_CODE, entity.getId()))) {
            assignMenuDTO.setMenuIds(
                sysMenuSvc.selectMenuByRole(MenuGroupEnum.SINGLE_ROLE, menuList));
          }
          // 兼职人员
          if (StrUtil.equalsIgnoreCase(
              role.getRoleCode(), StrUtil.format(ROLE_PARTTIME_USER_CODE, entity.getId()))) {
            assignMenuDTO.setMenuIds(sysMenuSvc.selectMenuByRole(MenuGroupEnum.DEPT, menuList));
          }
          // 系统管理员
          if (StrUtil.equalsIgnoreCase(
              role.getRoleCode(), StrUtil.format(ROLE_SYS_ADMIN_CODE, entity.getId()))) {
            assignMenuDTO.setMenuIds(menuListIds);
          }
          // 安全管理员
          if (StrUtil.equalsIgnoreCase(
              role.getRoleCode(), StrUtil.format(ROLE_SECURIT_CODE, entity.getId()))) {
            assignMenuDTO.setMenuIds(
                sysMenuSvc.selectMenuByRole(MenuGroupEnum.MANAGEMENT, menuList));
          }
          // 安全审计员
          if (StrUtil.equalsIgnoreCase(
              role.getRoleCode(), StrUtil.format(ROLE_AUDIT_CODE, entity.getId()))) {
            assignMenuDTO.setMenuIds(sysMenuSvc.selectMenuByRole(MenuGroupEnum.AUDIT, menuList));
          }

          // 单位领导
          if (StrUtil.equalsIgnoreCase(
              role.getRoleCode(), StrUtil.format(ROLE__UNIT_LEADER_CODE, entity.getId()))) {
            assignMenuDTO.setMenuIds(
                sysMenuSvc.selectMenuByRole(MenuGroupEnum.UNIT_LEADER, menuList));
          }

          // 档案部门领导
          if (StrUtil.equalsIgnoreCase(
              role.getRoleCode(), StrUtil.format(ROLE_ARCH_DEPT_LEADER_CODE, entity.getId()))) {
            assignMenuDTO.setMenuIds(
                sysMenuSvc.selectMenuByRole(MenuGroupEnum.ARCH_DEPT_LEADER, menuList));
          }
          // 部门领导
          if (StrUtil.equalsIgnoreCase(
              role.getRoleCode(), StrUtil.format(ROLE_DEPT_LEADER_CODE, entity.getId()))) {
            assignMenuDTO.setMenuIds(
                sysMenuSvc.selectMenuByRole(MenuGroupEnum.DEPT_LEADER, menuList));
          }
          assignMenuDTO.setRoleId(role.getId());
          assignMenuList.add(assignMenuDTO);
        });
    sysRoleSvc.assignMenu(assignMenuList);
  }
}
